package top.mcwebsite.lib.skeleton

import androidx.annotation.FloatRange
import androidx.compose.animation.core.*
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.util.lerp

interface SkeletonHighlight {
    fun brush(@FloatRange(from = 0.0, to = 1.0) progress: Float, size: Size): Brush

    val animationSpec: InfiniteRepeatableSpec<Float>?

    @FloatRange(from = 0.0, to = 1.0)
    public fun alpha(progress: Float): Float

    companion object
}

fun SkeletonHighlight.Companion.shimmer(
    highlightColor: Color,
    animationSpec: InfiniteRepeatableSpec<Float> = SkeletonDefault.shimmerAnimationSpec,
    @FloatRange(from = 0.0, to = 1.0) progressForMaxAlpha: Float = 0.6f
): SkeletonHighlight = Shimmer(
    highlightColor,
    animationSpec,
    progressForMaxAlpha
)

data class Shimmer(
    private val highlightColor: Color,
    override val animationSpec: InfiniteRepeatableSpec<Float>?,
    private val progressForMaxAlpha: Float,
) : SkeletonHighlight {
    override fun brush(progress: Float, size: Size): Brush = Brush.radialGradient(
        colors = listOf(
            highlightColor.copy(alpha = 0f),
            highlightColor,
            highlightColor.copy(alpha = 0f)
        ),
        center = Offset.Zero,
        radius = (maxOf(size.width, size.height) * progress * 2).coerceAtLeast(0.01f)
    )



    override fun alpha(progress: Float): Float =
        when {
            progress <= progressForMaxAlpha -> {
                lerp(
                    start = 0f,
                    stop = 1f,
                    fraction = progress / progressForMaxAlpha
                )
            }
            else -> {
                lerp(
                    start = 1f,
                    stop = 0f,
                    fraction = (progress - progressForMaxAlpha) / (1f - progressForMaxAlpha)
                )
            }
        }
}

object SkeletonDefault {

    val shimmerAnimationSpec: InfiniteRepeatableSpec<Float> by lazy {
        infiniteRepeatable(
            animation = tween(durationMillis = 1700, delayMillis = 200),
            repeatMode = RepeatMode.Restart
        )
    }
}